package com.zzyl.nursing.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.DeviceDataDto;
import com.zzyl.nursing.dto.DeviceDto;
import com.zzyl.nursing.dto.ElderSaveDTO;
import com.zzyl.nursing.mapper.DeviceDataMapper;
import com.zzyl.nursing.mapper.FamilyMemberElderMapper;
import com.zzyl.nursing.service.*;
import com.zzyl.nursing.vo.DeviceDataPointVo;
import com.zzyl.nursing.vo.ElderInfoVo;
import com.zzyl.nursing.vo.FamilyElderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;


/**
 * TODO
 *
 * @Date 2025/10/29 17:08
 */
@Service
public class FamilyMemberElderServiceImpl extends ServiceImpl<FamilyMemberElderMapper, FamilyMemberElder> implements FamilyMemberElderService {

    @Autowired
    private FamilyMemberElderMapper familyMemberElderMapper;
    @Autowired
    private IElderService elderService;
    @Autowired
    private IBedService bedService;
    @Autowired
    private IRoomService roomService;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DeviceDataMapper deviceDataMapper;
    /**
     * 绑定家人
     *
     * @param elderSaveDTO
     */
    @Transactional
    @Override
    public void add(ElderSaveDTO elderSaveDTO) {
        // 查询登录人id
        Long userId = UserThreadLocal.getUserId();
        // 根据请求数据进行查询
        Elder elder = elderService.lambdaQuery()
                .eq(Elder::getName, elderSaveDTO.getName())
                .eq(Elder::getIdCardNo, elderSaveDTO.getIdCard())
                .one();
        // 判断老人是否存在
        if (elder==null) {
            throw new BaseException("没有查到老人身份信息");
        }

        // 创建家属与老人绑定关系
        FamilyMemberElder familyMemberElder = new FamilyMemberElder();
        familyMemberElder.setElderId(elder.getId());
        familyMemberElder.setRemark(elderSaveDTO.getRemark());
        familyMemberElder.setFamilyMemberId(userId);
        familyMemberElder.setCreateBy(userId.toString());

        // 新增数据库
        this.save(familyMemberElder);
    }


    /**
     * 查询家人列表
     */
    @Override
    public List<FamilyElderVo> my() {
        // 查询用户ID 也就是FamilyMemberId
        Long userId = UserThreadLocal.getUserId();
        // 查询绑定的老人id集合
        List<FamilyMemberElder> familyMemberElderList = this.lambdaQuery().eq(FamilyMemberElder::getFamilyMemberId, userId).list();
        if (familyMemberElderList==null||familyMemberElderList.size()==0) {
            throw new BaseException("该用户没有绑定老人");
        }

        // 遍历
        List<FamilyElderVo> familyElderVoList = familyMemberElderList.stream().map(familyMemberElder -> {
            // 创建返回格式集合
            FamilyElderVo familyElderVo = new FamilyElderVo();

            // 创建关联老人id集合
            List<Elder> elderLists = elderService.lambdaQuery().eq(Elder::getId, familyMemberElder.getElderId()).list();
            // 封装家人列表返回vo对象
            elderLists.forEach(elder -> {
                familyElderVo.setId(familyMemberElder.getId());
                familyElderVo.setFamilyMemberId(userId);
                familyElderVo.setElderId(familyMemberElder.getElderId());
                familyElderVo.setElderName(elder.getName());
            });
            return familyElderVo;
        }).collect(Collectors.toList());
        return familyElderVoList;
    }

    /**
     * 查询家人列表(分页查询）
     * @return
     */
    @Override
    public List<ElderInfoVo> listPage() {
        // 查询用户ID 也就是mid
        Long userId = UserThreadLocal.getUserId();
        // 根据用户Id查询 关联的老人集合
        List<FamilyMemberElder> familyMemberElders = this.lambdaQuery().eq(FamilyMemberElder::getFamilyMemberId, userId).list();
        // 判断此用户id是否绑定了老人
        if (familyMemberElders==null||familyMemberElders.size()==0) {
            throw new BaseException("该用户没有绑定老人");
        }
        // 遍历用户Id关联的老人集合
        List<ElderInfoVo> elderInfoVoList = familyMemberElders.stream()
                .map(familyMemberElder -> {
            // 根据每个老人id查询老人信息
            Elder elder = elderService.lambdaQuery().eq(Elder::getId, familyMemberElder.getElderId()).one();
            // 根据老人信息查询房间类型
            Bed bed = bedService.lambdaQuery().eq(Bed::getBedNumber, elder.getBedNumber()).one();
            // 根据床位信息查询房间信息
            Room room = roomService.lambdaQuery().eq(Room::getId, bed.getRoomId()).one();
            // 根据老人姓名查找设备信息
            Device device = deviceService.lambdaQuery().eq(Device::getBindingLocation, elder.getId()).one();
                    // 新建返回集合
                ElderInfoVo elderInfoVo = new ElderInfoVo();
                // 添加返回元素
                elderInfoVo.setName(elder.getName());
                elderInfoVo.setMid(familyMemberElder.getId());
                elderInfoVo.setMremark(familyMemberElder.getRemark());
                elderInfoVo.setElderId(elder.getId().toString());
                elderInfoVo.setImage(elder.getImage());
                elderInfoVo.setBedNumber(elder.getBedNumber());
                elderInfoVo.setTypeName(room.getTypeName());
                elderInfoVo.setIotId(device != null ? device.getIotId():null);
                elderInfoVo.setDeviceName(device != null ? device.getDeviceName():null);
                elderInfoVo.setProductKey(device != null ? device.getProductKey():null);
            // 返回集合
            return elderInfoVo;
        }).collect(Collectors.toList());
        return  elderInfoVoList;
    }


    /**
     * 查询健康数据
     *
     * @return
     */
    @Override
    public Map<String,Object> queryDevicePropertyStatus(DeviceDto dto) {
        // 根据前端传来的参数查找IOT_ID
        Device device = deviceService.lambdaQuery().eq(Device::getDeviceName, dto.getDeviceName()).eq(Device::getProductKey, dto.getProductKey()).one();
        // 在redis中查找最后一次上报的数据
        String deviceDataJSON = redisTemplate.opsForHash().get(CacheConstants.IOT_DEVICE_DATA_LATEST, device.getIotId()).toString();



        List<Map> propertyStatusInfo = new ArrayList<>();
        // 解析
        List<DeviceData> deviceDataList = JSONUtil.toList(deviceDataJSON, DeviceData.class);
        // 遍历解析成功的数据，进行封装
        for (DeviceData deviceDatas : deviceDataList) {
            Map<String,Object> deviceData = new HashMap<>();
            deviceData.put("identifier",deviceDatas.getFunctionId());
//            LocalDateTime localDateTime = OffsetDateTime.parse(deviceDatas.getAlarmTime().toString(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss")).atZoneSameInstant(ZoneId.of("Asia/Shanghai")).toLocalDateTime();
//            deviceDatas.getAlarmTime()
            deviceData.put("time",deviceDatas.getAlarmTime().toInstant(ZoneId.of("Asia/Shanghai").getRules().getOffset(LocalDateTime.now())).toEpochMilli());
            deviceData.put("value",deviceDatas.getDataValue());
            propertyStatusInfo.add(deviceData);
        }
        // 将存入的心率换到第四位显示
        Collections.swap(propertyStatusInfo, 1, 3);

        Map<String,Object> List = new HashMap<>();
        List.put("propertyStatusInfo",propertyStatusInfo);

        Map<String,Object> returns = new HashMap<>();
        returns.put("list",List) ;

        return returns;
    }


    /**
     * 按天统计查询指标数据
     *
     */
    @Override
    public List<DeviceDataPointVo> queryDeviceDataListByDay(DeviceDataDto dto) {
        //转换时间格式
        LocalDateTime startTime = this.convertTimeFormat(dto.getStartTime());
        LocalDateTime endTime = this.convertTimeFormat(dto.getEndTime());
        return familyMemberElderMapper.queryDeviceDataListByDay(dto.getFunctionId(),dto.getIotId(),startTime,endTime);


    }
    private LocalDateTime convertTimeFormat(String time) {
        Long timestamp = Long.valueOf(time);
        LocalDateTime localDateTime = Instant.ofEpochMilli(timestamp)
                .atZone(ZoneId.of("Asia/Shanghai"))
                .toLocalDateTime();
        return localDateTime;
//        return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }


    /**
     * 按周统计查询指标数据
     *
     * @return
     */
    @Override
    public List<DeviceDataPointVo> queryDeviceDataListByWeek(DeviceDataDto dto) {
        //转换时间格式
        LocalDateTime startTime = this.convertTimeFormat(dto.getStartTime());
        LocalDateTime endTime = this.convertTimeFormat(dto.getEndTime());
        return familyMemberElderMapper.queryDeviceDataListByWeek(dto.getFunctionId(),dto.getIotId(),startTime,endTime);
    }

    /**
     * 解绑
     *
     * @param id
     */
    @Override
    public void deleteById(Long id) {
        this.removeById(id);
    }
}